{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch, torchvision\n",
    "import torch.nn as nn\n",
    "import torch.optim as optim\n",
    "from torch.optim import lr_scheduler\n",
    "import torchvision.datasets as datasets\n",
    "import torch.utils.data as data\n",
    "import torchvision.transforms as transforms\n",
    "from torch.autograd import Variable\n",
    "import torchvision.models as models\n",
    "import matplotlib.pyplot as plt\n",
    "import time, os, copy, numpy as np\n",
    "from livelossplot import PlotLosses\n",
    "from train_model import train_model\n",
    "from test_model import test_model\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_transforms = { 'train': transforms.Compose([transforms.ToTensor()]),\n",
    "                    'val'  : transforms.Compose([transforms.ToTensor(),]) }\n",
    "\n",
    "data_dir = 'images/224'\n",
    "image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x])\n",
    "                  for x in ['train', 'val']}\n",
    "dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=100, shuffle=True, num_workers=32)\n",
    "              for x in ['train', 'val']}\n",
    "dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Load Resnet18 with pretrained weights\n",
    "model_ft = models.resnet18(pretrained=True)\n",
    "#Finetune Final few layers to adjust for tiny imagenet input\n",
    "model_ft.avgpool = nn.AdaptiveAvgPool2d(1)\n",
    "num_ftrs = model_ft.fc.in_features\n",
    "model_ft.fc = nn.Linear(num_ftrs, 200)\n",
    "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n",
    "model_ft = model_ft.to(device)\n",
    "#Multi GPU\n",
    "model_ft = torch.nn.DataParallel(model_ft, device_ids=[0, 1])\n",
    "\n",
    "#Loss Function\n",
    "criterion = nn.CrossEntropyLoss()\n",
    "# Observe that all parameters are being optimized\n",
    "optimizer_ft = optim.SGD(model_ft.parameters(), lr=0.001, momentum=0.9)\n",
    "\n",
    "# Decay LR by a factor of 0.1 every 7 epochs\n",
    "exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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RERERCRGFLBEhjgzm2tmmgJYRESGLLVVIn0UsERERERERGJEAUskRszsY2b2hpmtNbMHzSxoZm1m9p9mtsHM/mpmRdFjLzSz18zsLTN70szyovurzew5M3vTzFabWVX09Jlm9nsz22xmj1l0JUQREZHzobZKJP4UsERiwMxqgb8FLnXOXQiEgb8DMoCVzrk6YBlwf/RHfgH8b+fcBcC6fvsfA37onJsGzAH2RfdPB74ATAbGA5fG/aJERCShqK0SGRwhvwsQSRDXABcBK6If2KUBzUAE+E30mEeBJ8wsB8h1zi2L7n8E+J2ZZQHlzrknAZxzHQDR873hnNsdfbwWGAu8FP/LEhGRBKK2SmQQKGCJxIYBjzjnvjxgp9nXTjrOvcfzd/b7Poz+dkVE5PyprRIZBBoiKBIbfwVuNbNiADPLN7NKvL+xW6PHfBR4yTnXChw2s8uj++8EljnnjgK7zezm6DlSzCx9UK9CREQSmdoqkUGgTxZEYsA5t9HMvgosNrMA0AXcCxwDZkWfa8Yb+w7w98DCaKPUAHwiuv9O4EEzeyB6jtsG8TJERCSBqa0SGRzm3HvtBRaRszGzNudcpt91iIiInInaKpHY0hBBERERERGRGFEPloiIiIiISIyoB0tERERERCRGFLBERERERERiRAFLREREREQkRhSwREREREREYkQBS0REREREJEYUsERERERERGLk/wMK697+IIObvQAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 864x576 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train Loss: 0.6797 Acc: 0.8400\n",
      "Val Loss: 1.0313 Acc: 0.7305\n",
      "Best Val Accuracy: 0.7305\n",
      "\n",
      "Training complete in 14m 51s\n",
      "Best val Acc: 0.730500\n"
     ]
    }
   ],
   "source": [
    "#Train\n",
    "model_ft = train_model(model_ft, dataloaders, dataset_sizes, criterion, optimizer_ft, exp_lr_scheduler,\n",
    "                       num_epochs=7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# torch.save(model_ft.state_dict(), \"./models/resnet18_224_w.pt\")\n",
    "# torch.save(model_ft, \"./models/resnet18_224_f.pt\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/1\n",
      "----------\n",
      "Iteration: 100/100, Loss: 750.4265785217285.Val Loss: 7.6722 Acc: 0.1531\n",
      "Best Val Accuracy: 0.1531\n",
      "\n",
      "Training complete in 0m 5s\n",
      "Best val Acc: 0.153100\n"
     ]
    }
   ],
   "source": [
    "data_transforms = { 'train': transforms.Compose([transforms.ToTensor()]),\n",
    "                    'val'  : transforms.Compose([transforms.ToTensor(),]) }\n",
    "\n",
    "data_dir = 'images/64'\n",
    "image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x])\n",
    "                  for x in ['train', 'val']}\n",
    "dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=100, shuffle=True, num_workers=32)\n",
    "              for x in ['train', 'val']}\n",
    "dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']}\n",
    "\n",
    "test_model(model_ft, dataloaders, dataset_sizes, criterion, optimizer_ft, exp_lr_scheduler, num_epochs=1)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
